package cn.yunyichina.provider.clinic.service.impl;

import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import cn.yunyichina.provider.clinic.hisiface.vo.ClinicVo;
import cn.yunyichina.provider.framework.dubbo.service.BaseService;
import cn.yunyichina.provider.framework.dubbo.service.HisifaceService;
import cn.yunyichina.provider.iface.entity.base.OrderExtVo;
import cn.yunyichina.provider.iface.entity.common.ResCommon;
import cn.yunyichina.provider.iface.entity.common.Response;
import cn.yunyichina.provider.iface.entity.hisiface.clinic.ClinicInsuranceVo;
import cn.yunyichina.provider.iface.entity.hisiface.clinic.ClinicInsuranceVoResponse;
import cn.yunyichina.utils.convert.JsonUtils;
import cn.yunyichina.utils.convert.ObjectParser;

/**
 * 门诊医保
 * 
 * @author zhangkewen
 * 
 */
@Service
public class InsuranceServiceImpl {
    private Logger logger = LoggerFactory.getLogger(InsuranceServiceImpl.class);
    
    /**
     * 门诊预结算-外部接口 yyt.clinic.insurance.out.get
     * 
     * @param data
     * @param sessionId
     * @return
     */
    public Response getInsuranceOut(String data, String sessionId) {
        logger.info("门诊预结算, 方法入参data=" + data + ", sessionId=" + sessionId);
        
        ClinicVo requestVo = JsonUtils.parseObject(data, ClinicVo.class);
        
        Response response = new Response();
        ClinicInsuranceVo insurancevo = new ClinicInsuranceVo();
        insurancevo.setHospitalCode(requestVo.getHospitalCode());
        insurancevo.setBranchCode(requestVo.getBranchCode());
        insurancevo.setPatCardNo(requestVo.getPatCardNo());
        insurancevo.setPatCardType(ObjectParser.toString(requestVo.getPatCardType()));
        insurancevo.setMzFeeId(requestVo.getMzFeeId());
        insurancevo.setMzBillId(requestVo.getMzBillId());
        insurancevo.setDeptCode(requestVo.getDeptCode());
        insurancevo.setDoctorCode(requestVo.getDoctorCode());
        insurancevo.setInsuranceSource(
                requestVo.getInsuranceSource() != null ? ObjectParser.toString(requestVo.getInsuranceSource()) : "0");
        insurancevo.setSessionId(sessionId);
        logger.info("门诊预结算, 就诊卡号" + requestVo.getPatCardNo() + ", 订单号"+requestVo.getPsOrdnum()+", 调hisiface模块, 门诊医保预结算入参request=" + JSON.toJSONString(insurancevo));
        ResCommon<ClinicInsuranceVoResponse> getClinicInsuranceResponse = HisifaceService.getHisifaceClient().getClinicInsurance(insurancevo);
        logger.info("门诊预结算, 就诊卡号" + requestVo.getPatCardNo() + ", 订单号"+requestVo.getPsOrdnum()+", 调hisiface模块, 门诊医保预结算返回response=" + requestVo.getPsOrdnum() + "预结算返回:"
                + JSON.toJSONString(getClinicInsuranceResponse));
        if (!ResCommon.SUCCESS_CODE.equals(getClinicInsuranceResponse.getResultCode())) {
            response.setResultCodeAndMessage("3006", "前置机返回预结算结果失败");
            return response;
        }
        
        response.setResult(JsonUtils.toJsonString(getClinicInsuranceResponse.getResult()));
        
        Map<String, String> dataMap = new HashMap<String, String>();
        dataMap.put("order_no", requestVo.getPsOrdnum());
        logger.info("门诊预结算, 就诊卡号" + requestVo.getPatCardNo() + ", 订单号"+requestVo.getPsOrdnum()+", 调base模块, 查询订单信息入参request=" + JSON.toJSONString(dataMap));
        Response ordResponse = BaseService.callUnderlineFromInternal(sessionId, "yyt.base.order.by.order.no.out.get",
                JsonUtils.toJsonString(dataMap));
        logger.info("门诊预结算, 就诊卡号" + requestVo.getPatCardNo() + ", 订单号"+requestVo.getPsOrdnum()+", 调base模块, 查询订单信息返回response=" + JSONObject.toJSONString(ordResponse));
        if (!"0".equals(ordResponse.getResultCode())) {
            response.setResultCodeAndMessage("3000", "查询订单失败。");
            return response;
        }
        OrderExtVo order = JsonUtils.parseObject(ordResponse.getResult(), OrderExtVo.class);
        
        // 由于前端没保存自费信息，所以后台需要保存自费信息，如果用户选回自费，需请求yyt.clinic.mzfee.selfpay.get获取自费金额。
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("pay_amount", order.getPayAmount());
        map.put("pay_real_amount", order.getPayRealAmount());
        map.put("account_amount", order.getAccountAmount());
        map.put("medicare_amount", order.getMedicareAmount());
        map.put("insurance_amount", order.getInsuranceAmount());
        map.put("total_amount", order.getTotalAmount());    
        
        ClinicInsuranceVoResponse getClinicInsuranceVoResponse = JsonUtils
                .parseObject(getClinicInsuranceResponse.getResult(), ClinicInsuranceVoResponse.class);
        order.setPayAmount(ObjectParser.toInteger(getClinicInsuranceVoResponse.getPayAmount()));
        order.setPayRealAmount(ObjectParser.toInteger(getClinicInsuranceVoResponse.getPayAmount()));
        order.setAccountAmount(ObjectParser.toInteger(getClinicInsuranceVoResponse.getAccountAmount()));
        order.setMedicareAmount(
                ObjectParser.toInteger(getClinicInsuranceVoResponse.getMedicareAmount()));
        order.setInsuranceAmount(
                ObjectParser.toInteger(getClinicInsuranceVoResponse.getInsuranceAmount()));
        order.setTotalAmount(ObjectParser.toInteger(getClinicInsuranceVoResponse.getTotalAmount()));
        
        // 如果自费+医保金额!=总金额，直接返回异常
        if ((order.getPayAmount().intValue() + order.getInsuranceAmount().intValue()) != order.getTotalAmount()
                .intValue()) {
            logger.info("门诊预结算, 就诊卡号" + requestVo.getPatCardNo() + ", 订单号" + order.getOrderNo()
                    + ", payAmount+insuranceAmount!=totalAmount, payAmount=" + order.getPayAmount().intValue()
                    + ", insuranceAmount=" + order.getInsuranceAmount().intValue() + ", totalAmount="
                    + order.getTotalAmount().intValue());
            response.setResultCodeAndMessage("3009", "自费金额加医保金额不等于总金额。");
            return response;
        }
        
        Map<String, String> extraParamsMap = JsonUtils.parseObject(order.getExtraParams(), HashMap.class);
        extraParamsMap.put("ss_bill_no", getClinicInsuranceVoResponse.getSsBillNo());
        extraParamsMap.put("ss_fee_no", getClinicInsuranceVoResponse.getSsFeeNo());
        extraParamsMap.put("cancel_bill_no", getClinicInsuranceVoResponse.getCancelBillNo());
        extraParamsMap.put("cancel_serial_no", getClinicInsuranceVoResponse.getCancelSerialNo());
        extraParamsMap.put("mz_category", getClinicInsuranceVoResponse.getMzCategory());
        extraParamsMap.put("recipe_count", getClinicInsuranceVoResponse.getRecipeCount() != null
                ? String.valueOf(getClinicInsuranceVoResponse.getRecipeCount()) : "");
        extraParamsMap.put("mz_fee_id", getClinicInsuranceVoResponse.getMzFeeId());
        extraParamsMap.put("mz_bill_id", getClinicInsuranceVoResponse.getMzBillId());
        extraParamsMap.put("pay_line", getClinicInsuranceVoResponse.getPayLine());
        extraParamsMap.put("selfpay_info", JSON.toJSONString(map));
        order.setExtraParams(JsonUtils.toJsonString(extraParamsMap));

        logger.info("门诊预结算, 就诊卡号" + requestVo.getPatCardNo() + ", 订单号"+requestVo.getPsOrdnum()+", 调base模块, 更新订单信息入参request=" + JSON.toJSONString(order));
        BaseService.callUnderlineFromInternal(sessionId, "yyt.base.order.update", JsonUtils.toJsonString(order));
        
        logger.info("门诊预结算, 就诊卡号" + requestVo.getPatCardNo() + ", 订单号"+requestVo.getPsOrdnum()+", 方法返回response=" + JSON.toJSONString(response));
        return response;
    }
}
